package net.yeah.mickey_zhouyou.util.fcs.elem;

import java.io.IOException;

import javax.script.ScriptContext;

import net.yeah.mickey_zhouyou.util.fcs.ReaderOverException;
import net.yeah.mickey_zhouyou.util.fcs.ReaderWrapper;
import net.yeah.mickey_zhouyou.util.fcs.SyntaxException;
import net.yeah.mickey_zhouyou.util.fcs.serialize.IConvertor;

public class Sentence {
	private static enum OpType {
		ASSIGNMENT, ADD
	}

	private Obj leftObj;
	private Obj rightObj;
	private OpType op;

	private Sentence(Obj leftObj, Obj rightObj, OpType op) {
		this.leftObj = leftObj;
		this.rightObj = rightObj;
		this.op = op;
	}

	public static Sentence create(ReaderWrapper reader) throws IOException {
		Obj leftObj = Obj.create(reader);
		if (leftObj != null) {
			if (leftObj instanceof ObjConstants)
				throw new SyntaxException("常量对象不能做为左值", reader.getCurrentRow(),
						reader.getCurrentColumn());
			OpType op = readOpType(reader);
			if (op == OpType.ASSIGNMENT) {
				if (leftObj.selectorList != null
						&& !leftObj.selectorList.isEmpty()
						&& !(leftObj.selectorList.get(leftObj.selectorList
								.size() - 1) instanceof FieldSelector))
					throw new SyntaxException(
							"当句子操作是一个赋值操作时，其左值要么是选择器，要么最后一个选择器为属性选择器",
							reader.getCurrentRow(), reader.getCurrentColumn());
			} else if (op == OpType.ADD) {
				if (leftObj.selectorList == null
						|| leftObj.selectorList.isEmpty()
						|| (!leftObj.selectorList.isEmpty() && !(leftObj.selectorList
								.get(leftObj.selectorList.size() - 1) instanceof FieldSelector)))
					throw new SyntaxException(
							"当句子操作是一个添加操作时，其左值的最后一个选择器必须为属性选择器",
							reader.getCurrentRow(), reader.getCurrentColumn());
			}
			Obj rightObj = Obj.create(reader);
			if (rightObj != null) {
				return new Sentence(leftObj, rightObj, op);
			}
			throw new SyntaxException("句子操作后面找不到其它对象", reader.getCurrentRow(),
					reader.getCurrentColumn());
		}
		return null;
	}

	private static OpType readOpType(ReaderWrapper reader) throws IOException {
		char c;
		try {
			c = reader.readNotBlank();
			if (c == '=')
				return OpType.ASSIGNMENT;
			else if (c == '<') {
				if (reader.read() == '-')
					return OpType.ADD;
			}
			throw new SyntaxException("错误的句子操作", reader.getCurrentRow(),
					reader.getCurrentColumn());
		} catch (ReaderOverException e) {
			throw new SyntaxException("一个句子必须有一个等号或一个<-符号！",
					reader.getCurrentRow(), reader.getCurrentColumn());
		}
	}

	public void eval(IConvertor objConvertor, ScriptContext context) {
		Obj.LeftValue leftValue = this.leftObj.asLeftValue(objConvertor,
				context, null);
		if (leftValue != null) {
			Object rightValue = this.rightObj.asRightValue(objConvertor,
					leftValue.getField(), context, null);
			if (this.op == OpType.ADD)
				leftValue.add(rightValue);
			else if (this.op == OpType.ASSIGNMENT)
				leftValue.assignment(rightValue, context);
			else
				throw new RuntimeException("不存在的语句操作");
		}
	}
}
